package com.atguigu.gmall.realtime.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisAsyncCommands;
import org.apache.commons.lang3.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * 操作redis的工具类
 * 旁路缓存
 *      思路：先从缓存中获取数据
 *          有：   直接将其作为返回值进行返回
 *          没有： 发送请求到HBase中进行查询，并将查询的结果放到缓存中进行缓存，方便下次查询
 *      缓存产品选型：
 *          状态：  性能好，维护性差
 *          redis：性能不错，维护性好
 *      关于redis的一些配置
 *          key；      维度表名：主键值 例如：dim_base_trademark:1
 *          类型：     String
 *          expire：  1day （避免冷数据常驻内存，给内存带来压力）
 *      注意：如果唯独数据有变化，需要将缓存中数据进行清理
 *
 *
 */
public class RedisUtil {

    private static JedisPool jedisPool;

    static {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMinIdle(5);//创建最少连接
        poolConfig.setMinIdle(5);
        poolConfig.setBlockWhenExhausted(true);
        poolConfig.setMaxWaitMillis(2000);
        poolConfig.setTestOnBorrow(true);
        jedisPool = new JedisPool(poolConfig, "hadoop102", 6379,10000);
    }

    public static Jedis getJedis(){
        System.out.println("获取jedis客户端");
        return jedisPool.getResource();
    }

    public static void closeJedis(Jedis jedis){
        if (jedis != null){
            System.out.println("关闭jedis客户端");
            jedis.close();
        }
    }

    // 从Redis中获取维度数据
    public static JSONObject readDim(Jedis jedis, String tableName, String id){
        String key = getKey(tableName, id);
        String dimJsonStr = jedis.get(key);
        if (StringUtils.isNotEmpty(dimJsonStr)){
            //缓存命中
            JSONObject dimJsonObj = JSON.parseObject(dimJsonStr);
            return dimJsonObj;
        }
        return null;
    }

    // 向Redis中放入维度数据
    public static void writeDim(Jedis jedis, String tableName, String id, JSONObject dimJsonObj){
        String key = getKey(tableName, id);
        jedis.setex(key,24*3600*1000,JSON.toJSONString(dimJsonObj));
    }


    public static StatefulRedisConnection<String, String> getRedisAsyncConnection(){
        System.out.println("获取jedis异步连接");
        RedisClient redisClient = RedisClient.create("redis://hadoop102:6379/2");
        return redisClient.connect();
    }

    public static void closeRedisAsyncConnection(StatefulRedisConnection<String, String> redisAsyncConn){
        if (redisAsyncConn != null){
            System.out.println("关闭jedis异步连接");
            redisAsyncConn.close();
        }
    }

    /**
     *
     * @param redisAsyncConn redis异步连接
     * @param tableName 表名
     * @param id id值
     * @return 读取到维度数据,封装的 json 对象中
     */
    public static JSONObject readDimAsync(StatefulRedisConnection<String, String> redisAsyncConn, String tableName, String id){
        RedisAsyncCommands<String, String> asyncCommand = redisAsyncConn.async();
        String key = getKey(tableName, id);
        try {
            String json = asyncCommand.get(key).get();
            if (json != null) {
                return JSON.parseObject(json);
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return null;

    }

    public static String getKey(String tableName, String id) {
        return tableName + ":" + id;
    }

    public static void main(String[] args) {
        String pong = getJedis().ping();
        System.out.println(pong);
    }
}
